package g11.actionutil;

import g11.dao.DAOException;
import g11.dao.EmployeeDAOImpl;
import g11.dao.PatientAssignmentDAO;
import g11.dao.PatientAssignmentDAOImpl;
import g11.dao.WorkForDAO;
import g11.dao.WorkForDAOImpl;
import g11.mis.PatientPermissionTypeEnum;
import g11.model.Employee;
import g11.model.Patient;

import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;

public class PatientUtilImpl implements PatientUtil {

	/*
	 * By Fern:this method can be used by both staff to assign a patient to a
	 * doctor(permission=0) and by a doctor to assign a patient to another
	 * doctor to read only(permission=1) so we do getPermission(doctor, patient)
	 * first, if the existing permission is not 0(not default doctor) and this
	 * permission is 0, then create it(even if a doctor can read only the
	 * patient, the doctor can be changed to default doctor);if the this
	 * permission is read only(permission=1), then create a new one only if
	 * there's no existing permission(permission=-1) . By Fern
	 * 
	 * (1)if the pemission is "belong to", that's 0, then first check if the
	 * patient is already "belong to" the doctor or another doctor if not, then
	 * create the assignment, (2) if the permission is "read only", that's 1,
	 * then check if the patient/doctor combination is already existed, if not
	 * create the entry
	 */
	private final Logger log = Logger.getLogger(this.getClass());

	public PatientUtilImpl() {

		log.info(this.getClass().toString());

	}

	public boolean assignPatientToDoctor(Patient patient, Employee doctor,
			byte permission) throws DAOException {
		PatientAssignmentDAO pADao = new PatientAssignmentDAOImpl();
		byte tempPermission = pADao.getPermission(doctor, patient);
		if ((tempPermission == -1 && permission == (byte) PatientPermissionTypeEnum.READONLY
				.index())
				|| (tempPermission != (byte) PatientPermissionTypeEnum.BELONGTO
						.index() && permission == (byte) PatientPermissionTypeEnum.BELONGTO
						.index())) {
			/*
			 * tempPermission == -1 means this patient and this doctor pair
			 * doesn't exist in the PatientAssignemnt table. so we can assign
			 * them with "read only". When the belong to assignment doesn't
			 * exist(tempPermission != 0), then need create the new assignment
			 * as belong to
			 */

			pADao.CreatePatientAssignment(doctor, patient, permission);
			return true;// succeeded
		}

		else
			return false;// failed
	}

	// this method revoke the read only relationship
	public boolean revokePatientToDoctor(Patient patient, Employee doctor)
			throws Exception {
		boolean status = false;
		PatientAssignmentDAO pADao = new PatientAssignmentDAOImpl();
		byte permission = pADao.getPermission(doctor, patient);
		if (permission == (byte) PatientPermissionTypeEnum.READONLY.index()) {
			/*
			 * the read only relationship does exist, then delete this from
			 * PatientAssignment table
			 */
			pADao.DeletePatientAssignment(doctor, patient);
			status = true;
		}
		// else the relationship doesn't exist(==-1) or is default type (==0)
		return status;
	}

	@Override
	public final Employee getDefaultDoctorByPatientId(final int patientId) {
		PatientAssignmentDAOImpl paDao = new PatientAssignmentDAOImpl();

		int defaultDoctorId = -1;

		try {
			defaultDoctorId = paDao.getDefaultDoctorIdByPatientId(patientId);
		} catch (DAOException e1) {
			e1.printStackTrace();
		}

		EmployeeDAOImpl eDAO = new EmployeeDAOImpl();
		Employee defaultDoctor = new Employee();
		try {
			defaultDoctor = eDAO.getEmployeeById(defaultDoctorId);
		} catch (DAOException e) {
			log.error(this.getClass().toString(), e);
			// e1.printStackTrace();
		}

		return defaultDoctor;
	}

	@Override
	public List<Patient> getPatientByStaffBelongTo(Employee staff)
			throws DAOException {
		List<Employee> doctorList = new ArrayList<Employee>();
		List<Patient> returnPatientList = new ArrayList<Patient>();
		WorkForDAO workForDAO = new WorkForDAOImpl();
		PatientAssignmentDAO patientAssignmentDAO = new PatientAssignmentDAOImpl();
		try {
			doctorList = workForDAO.getDoctorList(staff);
			for (Employee doctor : doctorList) {
				List<Patient> tempPatientList = new ArrayList<Patient>();
				tempPatientList = patientAssignmentDAO
						.getPatientByDoctorBelongTo(doctor);
				for (Patient tempPatient : tempPatientList) {
					returnPatientList.add(tempPatient);
				}
			}
		} catch (HibernateException e) {
			throw new DAOException(e.getMessage());
		}
		return returnPatientList;
	}

}
